/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable @typescript-eslint/no-explicit-any */
interface DebouncedFn<F extends (...args: any[]) => void> {
    (...args: Parameters<F>): void;
    cancel: () => void;
}

const debounce = <F extends (...args: any[]) => void>(callback: F, delay: number): DebouncedFn<F> => {
    let timeoutId: NodeJS.Timeout | null;

    const clear = () => {
        if (timeoutId != null) {
            clearTimeout(timeoutId);
            timeoutId = null;
        }
    };

    const debouncedFn = (...args: Parameters<F>): void => {
        clear();
        timeoutId = setTimeout(() => {
            callback(...args);
        }, delay);
    };

    debouncedFn.cancel = () => {
        clear();
    };

    return debouncedFn;
};
export default debounce;
